-- Copyright (c) 2024 Huawei Technologies Co., Ltd.
-- openUBMC is licensed under Mulan PSL v2.
-- You can use this software according to the terms and conditions of the Mulan PSL v2.
-- You may obtain a copy of Mulan PSL v2 at: http://license.coscl.org.cn/MulanPSL2
--
-- THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
-- EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
-- MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
-- See the Mulan PSL v2 for more details.

local vos = require 'utils.vos'
local utils = require 'mc.utils'

local m = {}

-- 处理器资源树接口
local JAR_FILE_PATH <const> = "/opt/bmc/web/htdocs/bmc/pages/jar/vconsole.jar"
local KVMIP_PATH_PATTERN = "/bmc/kepler/Managers/1/NetworkProtocol/KVMIP/"
local PORT_CONFIG_INTERFACE = "bmc.kepler.Managers.NetworkProtocol.PortConfig"
local GRAPHICAL_CONSOLE_PATH = "/bmc/kepler/Systems/%s/GraphicalConsole"
local GRAPHICAL_CONSOLE_INTF = "bmc.kepler.Systems.GraphicalConsole"
local SESSION_PATH = "/bmc/kepler/SessionService/Sessions"
local SESSION_INTF = "bmc.kepler.SessionService.Session"
local KVM_SESSION_PATH = "/bmc/kepler/SessionService/KVM"
local KVM_SESSION_INTF = "bmc.kepler.SessionService"
local DEFAULT_MAX_SESSION_NUM = 2

local function get_max_session_count()
    local ok, kvm_session = pcall(mdb.get_object, bus, KVM_SESSION_PATH, KVM_SESSION_INTF)
    if not ok then
        return DEFAULT_MAX_SESSION_NUM
    end
    return kvm_session.SessionMaxCount
end

local function get_number_of_active_sessions_and_type(system_id)
    local session_type
    local kvm_session_type
    local count = 0
    local activated_type = cjson.null
    local ok, sessions = pcall(mdb.get_sub_objects, bus, SESSION_PATH, SESSION_INTF)
    if not ok then
        sessions = {}
    end
    for _, session in pairs(sessions) do
        session_type = string.lower(session.SessionType)
        if session.SystemId == tonumber(system_id) and string.match(session_type, 'kvm') then
            kvm_session_type = session_type
            count = count + 1
        end
    end
    if count > 0 then
        activated_type = string.match(kvm_session_type, 'private') and 'Private' or 'Shared'
    end
    return count, activated_type
end

---是否显示Java KVM入口
---@return boolean
function m.check_jar_file_exist()
    return vos.get_file_accessible(JAR_FILE_PATH)
end

function m.get_graphical_console(system_ids)
    local res = cjson.json_object_new_array()
    if not system_ids or system_ids == cjson.null or #system_ids == 0 then
        return res
    end
    local ok
    local kvmip_obj
    local graphical_console_obj
    local graphical_console_path
    for _, system_id in ipairs(system_ids) do
        local data = cjson.json_object_new_object()
        data['SystemId'] = system_id
        ok, kvmip_obj = pcall(mdb.get_object, bus, KVMIP_PATH_PATTERN .. system_id, PORT_CONFIG_INTERFACE)
        if not ok or not kvmip_obj then
            data['Port'] = cjson.null
            data['Enabled'] = cjson.null
        else
            data['Port'] = kvmip_obj.Port
            data['Enabled'] = kvmip_obj.Enabled
        end
        graphical_console_path = string.format(GRAPHICAL_CONSOLE_PATH, system_id)
        ok, graphical_console_obj = pcall(mdb.get_object, bus, graphical_console_path, GRAPHICAL_CONSOLE_INTF)
        if not ok or not graphical_console_obj then
            data['PersistentUSBConnectionEnabled'] = cjson.null
            data['AutoOSLockEnabled'] = cjson.null
            data['AutoOSLockType'] = cjson.null
            data['AutoOSLockKey'] = cjson.null
            data['DisableKeyboardDuringBiosStartup'] = cjson.null
        else
            data['PersistentUSBConnectionEnabled'] = graphical_console_obj.PersistentUSBConnectionEnabled
            data['AutoOSLockEnabled'] = graphical_console_obj.AutoOSLockEnabled
            data['AutoOSLockType'] = graphical_console_obj.AutoOSLockType
            data['AutoOSLockKey'] = cjson.json_object_from_table(graphical_console_obj.AutoOSLockKey)
            data['DisableKeyboardDuringBiosStartup'] = graphical_console_obj.DisableKeyboardDuringBiosStartup
        end
        data['MaximumNumberOfSessions'] = get_max_session_count()
        data['NumberOfActiveSessions'], data['ActivatedSessionsType'] = get_number_of_active_sessions_and_type(system_id)
        res[#res+1] = data
    end
    return res
end

function m.parse_graphical_console(input)
    local data = input[1]
    local system_ids = input[2] or {}
    local res = cjson.json_object_new_object()
    if not data or data == cjson.null or #data == 0 then
        return res
    end
    local err
    for _, sub_data in ipairs(data) do
        if not sub_data.SystemId then
            err = base_messages.PropertyMissing('SystemId')
            err.RelatedProperties = {'#/GetGraphicalConsole/SystemId'}
            error(err)
        end
        if not utils.array_contains(system_ids, sub_data.SystemId) then
            err = custom_messages.OperationNotSupport()
            err.RelatedProperties = {'#/GetGraphicalConsole/SystemId'}
            error(err)
        end
        local tmp_data = cjson.json_object_new_object()
        tmp_data['Port'] = sub_data.Port
        tmp_data['Enabled'] = sub_data.Enabled
        tmp_data['PersistentUSBConnectionEnabled'] = sub_data.PersistentUSBConnectionEnabled
        tmp_data['AutoOSLockEnabled'] = sub_data.AutoOSLockEnabled
        tmp_data['AutoOSLockType'] = sub_data.AutoOSLockType
        tmp_data['AutoOSLockKey'] = sub_data.AutoOSLockKey
        tmp_data['DisableKeyboardDuringBiosStartup'] = sub_data.DisableKeyboardDuringBiosStartup
        res[sub_data.SystemId] = tmp_data
    end
    return res
end

return m
